package consume;

import consume.entity.User;
import org.springframework.jms.annotation.JmsListener;
import org.springframework.stereotype.Component;

import javax.jms.*;
import java.io.FileOutputStream;
import java.io.Serializable;

/**
 * @author xiaohong
 * @version 1.0
 * @date 2021/11/14 0014 17:01
 * @description 消费者
 */
@Component
public class ConsumeController {

    /**
     * 接收消息
     * TextMessage-- 字符串对象
     * MapMessage-- 名称-值对
     * objectMessage-- 序列化的Java对象
     * BytesMessage-- 字节的数据流
     * streamMessage -- Java原始值的数据流
     * @param message
     */
//    @JmsListener(destination = "queue",containerFactory = "jmsListenerContainerFactory") // 关闭默认事务
    @JmsListener(destination = "queue")
    public void textListener(Message message,Session session){

        try {
            // 文本消息
            if (message instanceof TextMessage){
                TextMessage textMessage = (TextMessage) message;
                try {
                    // 获取消息请求头
                    String jmsCorrelationID = message.getJMSCorrelationID();
                    System.out.println("jmsCorrelationID:"+jmsCorrelationID);

                    // 获取消息属性
                    System.out.println("消息属性:"+message.getStringProperty("标记"));

                    System.out.println("接收到文本消息："+textMessage.getText());
                } catch (JMSException e) {
                    e.printStackTrace();
                }
            }

            // map消息
            if (message instanceof MapMessage){
                MapMessage mapMessage = (MapMessage) message;
                try {
                    System.out.println("姓名："+mapMessage.getString("name"));
                    System.out.println("年龄："+mapMessage.getInt("age"));
                } catch (JMSException e) {
                    e.printStackTrace();
                }
            }

            // 对象消息
            if (message instanceof ObjectMessage){
                ObjectMessage objectMessage = (ObjectMessage) message;
                try {
                    // 这里接收是转换的对象要和发送的对象在同样的目录下才能转换  不然会报错 produce.entity.User
                    // 像这里的User是consume.entity.User 就会报错
                    // 当然即便是对象一样，还需要在配置文件中将将该对象添加到受信任列表
                    User user = (User) objectMessage.getObject();

                    System.out.println(user);
                } catch (JMSException e) {
                    e.printStackTrace();
                }
            }


            // 字节消息
            if (message instanceof BytesMessage){
                BytesMessage bytesMessage = (BytesMessage) message;
                try {
                    // 设计缓存数组
                    byte[] buffer = new byte[(int) bytesMessage.getBodyLength()];

                    //将字节消息的内容写入到缓存数组中
                    bytesMessage.readBytes(buffer);

                    // 构建文件输出流
                    FileOutputStream fileOutputStream = new FileOutputStream("F:\\IDEA-workspace\\MQProject\\MQParent\\ActiveMQ\\activemq-consume\\src\\main\\resources\\b.txt");

                    // 将数据写出到本地硬盘
                    fileOutputStream.write(buffer);

                    System.out.println("接收的字节消息长度："+bytesMessage.getBodyLength());

                } catch (Exception e) {
                    e.printStackTrace();
                }
            }

            // 流消息
            if (message instanceof StreamMessage){
                StreamMessage streamMessage = (StreamMessage) message;
                try {
                    String s = streamMessage.readString();
                    int i = streamMessage.readInt();
                    System.out.println(s);
                    System.out.println(i);
                } catch (JMSException e) {
                    e.printStackTrace();
                }
            }

            // 提交事务 事务会话中 当一个事务被提交的时候，确认自动发生
            // 事务在消费方默认存在
            // 消息确认机制与事务机制是冲突的，只能选其中一个，所以演示消息确认之前，先关闭事务
            session.commit();

            // 手动消息确认
//            message.acknowledge();

        }catch (Exception e){
            e.printStackTrace();
            // 回滚事务
            try {
                session.rollback(); // 一旦事务回滚，MQ会重发消息，一共会重发6次 最终会放到死信队列
            } catch (JMSException ex) {
                ex.printStackTrace();
            }
        }


    }


}
